1 /*
2  * Copyright (c) 2013-2014 - Andre Roth <neolynx@gmail.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License as published by
6  * the Free Software Foundation version 2.1 of the License.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU Lesser General Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16  * Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
17  *
18  */
19 
20 module libdvbv5_d.mpeg_pes;
21 
22 import core.sys.posix.unistd;
23 
24 import libdvbv5_d.dvb_fe: dvb_v5_fe_parms;
25 
26 extern (C):
27 
28 /**
29  * @file mpeg_pes.h
30  * @ingroup dvb_table
31  * @brief Provides the table parser for the MPEG-PES Elementary Stream
32  * @copyright GNU Lesser General Public License version 2.1 (LGPLv2.1)
33  * @author Andre Roth
34  *
35  * @par Relevant specs
36  * The table described herein is defined in ISO 13818-1
37  *
38  * @see
39  * http://dvd.sourceforge.net/dvdinfo/pes-hdr.html
40  *
41  * @par Bug Report
42  * Please submit bug reports and patches to linux-media@vger.kernel.org
43  */
44 
45 /* ssize_t */
46 
47 /**
48  * @def DVB_MPEG_PES
49  *	@brief MPEG Packetized Elementary Stream magic
50  *	@ingroup dvb_table
51  * @def DVB_MPEG_PES_AUDIO
52  *	@brief PES Audio
53  *	@ingroup dvb_table
54  * @def DVB_MPEG_PES_VIDEO
55  *	@brief PES Video
56  *	@ingroup dvb_table
57  * @def DVB_MPEG_STREAM_MAP
58  *	@brief PES Stream map
59  *	@ingroup dvb_table
60  * @def DVB_MPEG_STREAM_PADDING
61  *	@brief PES padding
62  *	@ingroup dvb_table
63  * @def DVB_MPEG_STREAM_PRIVATE_2
64  *	@brief PES private
65  *	@ingroup dvb_table
66  * @def DVB_MPEG_STREAM_ECM
67  *	@brief PES ECM Stream
68  *	@ingroup dvb_table
69  * @def DVB_MPEG_STREAM_EMM
70  *	@brief PES EMM Stream
71  *	@ingroup dvb_table
72  * @def DVB_MPEG_STREAM_DIRECTORY
73  *	@brief PES Stream directory
74  *	@ingroup dvb_table
75  * @def DVB_MPEG_STREAM_DSMCC
76  *	@brief PES DSMCC
77  *	@ingroup dvb_table
78  * @def DVB_MPEG_STREAM_H222E
79  *	@brief PES H.222.1 type E
80  *	@ingroup dvb_table
81  */
82 
83 enum DVB_MPEG_PES = 0x00001;
84 
85 enum DVB_MPEG_STREAM_MAP = 0xBC;
86 enum DVB_MPEG_STREAM_PADDING = 0xBE;
87 enum DVB_MPEG_STREAM_PRIVATE_2 = 0x5F;
88 enum DVB_MPEG_STREAM_ECM = 0x70;
89 enum DVB_MPEG_STREAM_EMM = 0x71;
90 enum DVB_MPEG_STREAM_DIRECTORY = 0xFF;
91 enum DVB_MPEG_STREAM_DSMCC = 0x7A;
92 enum DVB_MPEG_STREAM_H222E = 0xF8;
93 
94 /**
95  * @struct ts_t
96  * @brief MPEG PES timestamp structure, used for dts and pts
97  * @ingroup dvb_table
98  *
99  * @param tag		4 bits  Should be 0010 for PTS and 0011 for DTS
100  * @param bits30	3 bits	Timestamp bits 30-32
101  * @param one		1 bit	Sould be 1
102  * @param bits15	15 bits	Timestamp bits 15-29
103  * @param one1		1 bit	Should be 1
104  * @param bits00	15 Bits	Timestamp bits 0-14
105  * @param one2		1 bit	Should be 1
106  */
107 
108 struct ts_t
109 {
110     import std.bitmanip : bitfields;
111     align (1):
112 
113     mixin(bitfields!(
114         ubyte, "one", 1,
115         ubyte, "bits30", 3,
116         ubyte, "tag", 4));
117 
118     union
119     {
120         align (1):
121 
122         ushort bitfield;
123 
124         struct
125         {
126             import std.bitmanip : bitfields;
127             align (1):
128 
129             mixin(bitfields!(
130                 ushort, "one1", 1,
131                 ushort, "bits15", 15));
132         }
133     }
134 
135     union
136     {
137         align (1):
138 
139         ushort bitfield2;
140 
141         struct
142         {
143             import std.bitmanip : bitfields;
144             align (1):
145 
146             mixin(bitfields!(
147                 ushort, "one2", 1,
148                 ushort, "bits00", 15));
149         }
150     }
151 }
152 
153 /**
154  * @struct dvb_mpeg_pes_optional
155  * @brief MPEG PES optional header
156  * @ingroup dvb_table
157  *
158  * @param two				2 bits	Should be 10
159  * @param PES_scrambling_control	2 bits	PES Scrambling Control (Not Scrambled=00, otherwise scrambled)
160  * @param PES_priority			1 bit	PES Priority
161  * @param data_alignment_indicator	1 bit	PES data alignment
162  * @param copyright			1 bit	PES content protected by copyright
163  * @param original_or_copy		1 bit	PES content is original (=1) or copied (=0)
164  * @param PTS_DTS			2 bit	PES header contains PTS (=10, =11) and/or DTS (=01, =11)
165  * @param ESCR				1 bit	PES header contains ESCR fields
166  * @param ES_rate			1 bit	PES header contains ES_rate field
167  * @param DSM_trick_mode		1 bit	PES header contains DSM_trick_mode field
168  * @param additional_copy_info		1 bit	PES header contains additional_copy_info field
169  * @param PES_CRC			1 bit	PES header contains CRC field
170  * @param PES_extension			1 bit	PES header contains extension field
171  * @param length			8 bit	PES header data length
172  * @param pts				64 bit	PES PTS timestamp
173  * @param dts				64 bit	PES DTS timestamp
174  */
175 struct dvb_mpeg_pes_optional
176 {
177     align (1):
178 
179     union
180     {
181         align (1):
182 
183         ushort bitfield;
184 
185         struct
186         {
187             import std.bitmanip : bitfields;
188             align (1):
189 
190             mixin(bitfields!(
191                 ushort, "PES_extension", 1,
192                 ushort, "PES_CRC", 1,
193                 ushort, "additional_copy_info", 1,
194                 ushort, "DSM_trick_mode", 1,
195                 ushort, "ES_rate", 1,
196                 ushort, "ESCR", 1,
197                 ushort, "PTS_DTS", 2,
198                 ushort, "original_or_copy", 1,
199                 ushort, "copyright", 1,
200                 ushort, "data_alignment_indicator", 1,
201                 ushort, "PES_priority", 1,
202                 ushort, "PES_scrambling_control", 2,
203                 ushort, "two", 2));
204         }
205     }
206 
207     ubyte length;
208     ulong pts;
209     ulong dts;
210 }
211 
212 /**
213  * @struct dvb_mpeg_pes
214  * @brief MPEG PES data structure
215  * @ingroup dvb_table
216  *
217  * @param sync		24 bits	DVB_MPEG_PES
218  * @param stream_id	8 bits	PES Stream ID
219  * @param length	16 bits	PES packet length
220  * @param optional	Pointer to optional PES header
221  */
222 struct dvb_mpeg_pes
223 {
224     align (1):
225 
226     union
227     {
228         align (1):
229 
230         uint bitfield;
231 
232         struct
233         {
234             import std.bitmanip : bitfields;
235             align (1):
236 
237             mixin(bitfields!(
238                 uint, "stream_id", 8,
239                 uint, "sync", 24));
240         }
241     }
242 
243     ushort length;
244     dvb_mpeg_pes_optional[] optional;
245 }
246 
247 // struct dvb_v5_fe_parms;
248 
249 /**
250  * @brief Initialize a struct dvb_mpeg_pes from buffer
251  * @ingroup dvb_table
252  *
253  * @param parms		struct dvb_v5_fe_parms for log functions
254  * @param buf		Buffer
255  * @param buflen	Length of buffer
256  * @param table		Pointer to allocated struct dvb_mpeg_pes
257  *
258  * @return		Length of data in table
259  *
260  * This function copies the length of struct dvb_mpeg_pes
261  * to table and fixes endianness. The pointer table has to be
262  * allocated on stack or dynamically.
263  */
264 ssize_t dvb_mpeg_pes_init (
265     dvb_v5_fe_parms* parms,
266     const(ubyte)* buf,
267     ssize_t buflen,
268     ubyte* table);
269 
270 /**
271  * @brief Deallocate memory associated with a struct dvb_mpeg_pes
272  * @ingroup dvb_table
273  *
274  * @param pes	struct dvb_mpeg_pes to be deallocated
275  *
276  * If the pointer pes was allocated dynamically, this function
277  * can be used to free the memory.
278  */
279 void dvb_mpeg_pes_free (dvb_mpeg_pes* pes);
280 
281 /**
282  * @brief Print details of struct dvb_mpeg_pes
283  * @ingroup dvb_table
284  *
285  * @param parms		struct dvb_v5_fe_parms for log functions
286  * @param pes    	Pointer to struct dvb_mpeg_pes to print
287  *
288  * This function prints the fields of struct dvb_mpeg_pes
289  */
290 void dvb_mpeg_pes_print (dvb_v5_fe_parms* parms, dvb_mpeg_pes* pes);